import random
import time

import pytest
import requests
import json
from unittest.mock import patch, MagicMock

# 配置信息
API_URL = "https://cvm.tencentcloudapi.com/"
REGION = "ap-guangzhou"
SECRET_ID = "your-secret-id"
SECRET_KEY = "your-secret-key"


def generate_signature(params, secret_key):
    """生成签名（模拟实现）"""
    return "mock-signature"


def send_request(action, params):
    """发送API请求（模拟实现）"""
    common_params = {
        "Action": action,
        "Version": "2017-03-12",
        "Region": REGION,
        "SecretId": SECRET_ID,
        "Timestamp": int(time.time()),
        "Nonce": random.randint(1, 1000000),
        "SignatureMethod": "HmacSHA256"
    }
    all_params = {**common_params, **params}
    all_params["Signature"] = generate_signature(all_params, SECRET_KEY)

    response = requests.post(API_URL, data=all_params)
    return response.json()


class TestFlashFpgaImage:
    @patch('requests.post')
    def test_flash_success(self, mock_post):
        """测试成功烧录FPGA镜像"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "RequestId": "1234567890",
                "TaskId": "task-123456"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "FpgaImageId": "img-valid-id",
            "FpgaDeviceId": "device-valid-id"
        }
        result = send_request("FlashFpgaImage", params)

        assert "Response" in result
        assert "TaskId" in result["Response"]

    @patch('requests.post')
    def test_internal_error(self, mock_post):
        """测试内部错误"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InternalError",
                    "Message": "操作内部错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("FlashFpgaImage", {"InstanceId": "ins-valid-id"})
        assert result["Response"]["Error"]["Code"] == "InternalError"

    @patch('requests.post')
    def test_invalid_instance_id(self, mock_post):
        """测试无效实例ID"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstanceId.NotFound",
                    "Message": "实例不存在"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("FlashFpgaImage", {"InstanceId": "ins-invalid-id"})
        assert result["Response"]["Error"]["Code"] == "InvalidInstanceId.NotFound"

    @patch('requests.post')
    def test_invalid_fpga_image_id(self, mock_post):
        """测试无效FPGA镜像ID"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidFpgaImageId.NotFound",
                    "Message": "FPGA镜像不存在"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "FpgaImageId": "img-invalid-id",
            "FpgaDeviceId": "device-valid-id"
        }
        result = send_request("FlashFpgaImage", params)
        assert result["Response"]["Error"]["Code"] == "InvalidFpgaImageId.NotFound"

    @patch('requests.post')
    def test_invalid_fpga_device_id(self, mock_post):
        """测试无效FPGA设备ID"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidFpgaDeviceId.NotFound",
                    "Message": "FPGA设备不存在"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "FpgaImageId": "img-valid-id",
            "FpgaDeviceId": "device-invalid-id"
        }
        result = send_request("FlashFpgaImage", params)
        assert result["Response"]["Error"]["Code"] == "InvalidFpgaDeviceId.NotFound"

    @patch('requests.post')
    def test_instance_not_support_fpga(self, mock_post):
        """测试实例不支持FPGA"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstance.NotSupportFpga",
                    "Message": "实例不支持FPGA"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("FlashFpgaImage", {"InstanceId": "ins-not-support-fpga"})
        assert result["Response"]["Error"]["Code"] == "InvalidInstance.NotSupportFpga"

    @patch('requests.post')
    def test_fpga_device_not_attached(self, mock_post):
        """测试FPGA设备未挂载"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidFpgaDevice.NotAttached",
                    "Message": "FPGA设备未挂载到实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "FpgaImageId": "img-valid-id",
            "FpgaDeviceId": "device-not-attached"
        }
        result = send_request("FlashFpgaImage", params)
        assert result["Response"]["Error"]["Code"] == "InvalidFpgaDevice.NotAttached"

    @patch('requests.post')
    def test_fpga_image_not_compatible(self, mock_post):
        """测试FPGA镜像不兼容"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidFpgaImage.Incompatible",
                    "Message": "FPGA镜像与设备不兼容"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "FpgaImageId": "img-incompatible",
            "FpgaDeviceId": "device-valid-id"
        }
        result = send_request("FlashFpgaImage", params)
        assert result["Response"]["Error"]["Code"] == "InvalidFpgaImage.Incompatible"

    @patch('requests.post')
    def test_fpga_image_not_verified(self, mock_post):
        """测试FPGA镜像未验证"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidFpgaImage.NotVerified",
                    "Message": "FPGA镜像未通过验证"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "FpgaImageId": "img-not-verified",
            "FpgaDeviceId": "device-valid-id"
        }
        result = send_request("FlashFpgaImage", params)
        assert result["Response"]["Error"]["Code"] == "InvalidFpgaImage.NotVerified"

    @patch('requests.post')
    def test_instance_state_invalid(self, mock_post):
        """测试实例状态不允许操作"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstanceState",
                    "Message": "实例状态不允许此操作"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("FlashFpgaImage", {"InstanceId": "ins-invalid-state"})
        assert result["Response"]["Error"]["Code"] == "InvalidInstanceState"

    @patch('requests.post')
    def test_missing_instance_id(self, mock_post):
        """测试缺少实例ID参数"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "MissingParameter.InstanceId",
                    "Message": "缺少实例ID参数"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("FlashFpgaImage", {})
        assert result["Response"]["Error"]["Code"] == "MissingParameter.InstanceId"

    @patch('requests.post')
    def test_missing_fpga_image_id(self, mock_post):
        """测试缺少FPGA镜像ID参数"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "MissingParameter.FpgaImageId",
                    "Message": "缺少FPGA镜像ID参数"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "FpgaDeviceId": "device-valid-id"
        }
        result = send_request("FlashFpgaImage", params)
        assert result["Response"]["Error"]["Code"] == "MissingParameter.FpgaImageId"

    @patch('requests.post')
    def test_missing_fpga_device_id(self, mock_post):
        """测试缺少FPGA设备ID参数"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "MissingParameter.FpgaDeviceId",
                    "Message": "缺少FPGA设备ID参数"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "FpgaImageId": "img-valid-id"
        }
        result = send_request("FlashFpgaImage", params)
        assert result["Response"]["Error"]["Code"] == "MissingParameter.FpgaDeviceId"

    @patch('requests.post')
    def test_operation_conflict(self, mock_post):
        """测试操作冲突"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "OperationDenied.Conflict",
                    "Message": "操作冲突，FPGA设备正在进行其他操作"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "FpgaImageId": "img-valid-id",
            "FpgaDeviceId": "device-in-conflict"
        }
        result = send_request("FlashFpgaImage", params)
        assert result["Response"]["Error"]["Code"] == "OperationDenied.Conflict"

    @patch('requests.post')
    def test_permission_denied(self, mock_post):
        """测试权限不足"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "AuthFailure.UnauthorizedOperation",
                    "Message": "权限不足"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceId": "ins-valid-id",
            "FpgaImageId": "img-valid-id",
            "FpgaDeviceId": "device-valid-id"
        }
        result = send_request("FlashFpgaImage", params)
        assert result["Response"]["Error"]["Code"] == "AuthFailure.UnauthorizedOperation"


# 启动测试函数
def run_tests():
    pytest.main([__file__, "-v", "-s"])


if __name__ == "__main__":
    run_tests()